<template>
	<view v-if="!isLoading && msgList.length">
		<up-list
			@scrolltolower="scrolltolower"
			class="cell-list"
			scroll-y
			@scroll="onScroll"
			ref="listRef">
			<up-line></up-line>
			<up-list-item
				v-for="(item, index) in msgList"
				:key="`item-${index}`">
				<up-cell @click="openPop(item)">
					<template #title>
						<view class="tilte-box">
							<view class="top-box">
								<text class="title">
									{{ getTitle(item.code) }}
								</text>
								<text class="time">
									{{ formatTime(item.create_time) }}
								</text>
							</view>
							<text class="bottom-text">
								{{ formatDeviceEvent(item) }}
							</text>
						</view>
					</template>
					<template #icon>
						<view class="img-box">
							<up-avatar
								shape="square"
								size="48"
								:src="
									'/static/image/info/icon/' +
									getIcons(item.code) +
									'.png'
								"
								customStyle="margin: -3px 5px -3px 0"></up-avatar>
							<view class="bot" v-if="!item.isRead"></view>
						</view>
					</template>
				</up-cell>
			</up-list-item>
		</up-list>
	</view>
	<view class="loading" v-show="isLoading">
		<LoadingDots />
	</view>
	<up-empty
		v-if="!msgList.length && !isLoading"
		icon="@/static/image/common/noData.svg"
		width="35%"
		textSize="18"
		text-color="#b8b8b8"
		safeAreaInsetBottom
		:text="t('noList')"></up-empty>
	<up-popup
		:show="showPop"
		:round="10"
		@close="closePop"
		safeAreaInsetBottom
		closeOnClickOverlay>
		<view class="pop-content">
			<view class="pop-top">
				<up-avatar
					shape="square"
					size="48"
					:src="
						'/static/image/info/icon/' +
						getIcons(seeItem.code) +
						'.png'
					"
					customStyle="margin: -3px 5px -3px 0"></up-avatar>
				<text>{{ formatDeviceEvent(seeItem) }}</text>
			</view>
			<up-form labelPosition="left" :model="seeItem" ref="form">
				<up-form-item :label="t('device.device.name')">
					{{ seeItem.device_name }}
				</up-form-item>
				<up-form-item :label="t('device.device.model')">
					{{ seeItem.model_name }}
				</up-form-item>
				<up-form-item :label="t('device.device.sn')">
					{{ seeItem.device_sn }}
				</up-form-item>
				<up-form-item :label="t('time')">
					{{ formatTime(seeItem.create_time) }}
				</up-form-item>
			</up-form>
		</view>
	</up-popup>
</template>

<script setup lang="ts">
import {
	ref,
	reactive,
	onMounted,
	computed,
	watch,
	nextTick,
	unref,
	defineExpose,
} from "vue";

import LoadingDots from "@/components/LoadingDots/index.vue";
import { onLoad, onShow } from "@dcloudio/uni-app";
import type * as type from "./type";
import { parseMsg } from "./parseMsg";
import { getMsg, getEventApi } from "@/service/index";
import { useI18n } from "vue-i18n";
const { locale, t } = useI18n();
import moment from "moment-timezone";
// 响应式数据
const msgList = ref<type.MsgItem[]>([]);
const formRef = ref(null);
const isShowMsg = ref(false);
const isEnd = ref(false);
const isLoading = ref(false);
const listRef = ref(null);
const scrollPosition = ref(0);
const showPop = ref(false);
const seeItem = ref<type.MsgItem>();
const readArrStore: any = useUniversalStorage("readArr", []);
const allReadTimeStore: any = useUniversalStorage("allReadTime", null);
const query = ref<QueryParams>({
	page: 1,
	pageSize: 10,
	type: "push",
});
const emit = defineEmits(["changeCount"]);
const props = defineProps<{
	pushTitleList: type.PushTitleItem[];
	type: string;
	deviceSn?: string;
}>();
watch(
	() => props.type,
	(newVal) => {
		if (!newVal) return;
		clearAll();
		if ("sub_type" in query.value && newVal === "push") {
			delete query.value.sub_type;
		} else if (newVal !== "push") {
			query.value.sub_type = newVal;
		}
		isLoading.value = true;
		getMsglist();
	},
	{ deep: true }
);
const clearAll = () => {
	query.value.page = 1;
	query.value.pageSize = 10;
	msgList.value = [];
	scrollPosition.value = 0;
};
const imgMap: Record<type.ImgCode, type.ImgResult> = {
	2214001: "push1",
	4214002: "push2",
	3106013: "push3",
	4214006: "push4",
	3214003: "push5",
	3214004: "push6",
	4214007: "repair",
};

function getIcons(code: number): type.ImgResult {
	return imgMap[code as type.ImgCode] ?? 1; // 使用类型断言 + 空值合并运算符
}
const codeJson = ref<type.EventCodeItem[]>([]);
const closePop = () => {
	showPop.value = false;
};
const openPop = (item: type.MsgItem) => {
	seeItem.value = item;
	const readArr = Array.isArray(readArrStore.value) ? readArrStore.value : [];
	readArrStore.value = [...new Set([...readArr, item.event_id])];
	nextTick(() => {
		getNewMsgList();
		emit("changeCount");
	});

	showPop.value = true;
};
const getEventInfo = (code: string | number): string => {
	if (!codeJson.value.length) return "";

	// 标准化代码比较（忽略前缀字符）
	const normalizeCode = (rawCode: string | number): number => {
		const codeStr = String(rawCode);
		return Number(codeStr.substring(1)); // 忽略第一个字符
	};

	const targetCode = normalizeCode(code);
	const matchedItem = codeJson.value.find(
		(item) => normalizeCode(item.code) === targetCode
	);

	return matchedItem?.info || "Msg返回为空";
};
const formatDeviceEvent = (item: type.EventItem) => {
	return [
		item.device_name || item.device_sn,
		item.msg ? parseMsg(item.msg) : getEventInfo(item.code),
	].join(" ");
};
const getTitle = (id: string | number): string => {
	const matchedItem = props.pushTitleList.find((item) => item.code === id);
	if (matchedItem) {
		return computed(() =>
			locale.value === "zh" ? matchedItem.ch : matchedItem.en
		).value;
	}

	return `${t("classify.no")} - ${id}`;
};
const addZero = (num: number): string => (num < 10 ? `0${num}` : `${num}`);
const timeZoneStore = useUniversalStorage<string>(
	"SELECTED_TIMEZONE",
	"Asia/Shanghai"
);
const formatTime = (
	timestamp: string | number,
	options: type.TimeFormatOptions = { showSeconds: true, separator: "-" }
): string => {
	if (!timestamp) return "";

	// 统一转换为毫秒
	const timeMs =
		typeof timestamp === "string" ? parseInt(timestamp) : timestamp;
	const normalizedTime = timeMs < 1e12 ? timeMs * 1000 : timeMs; // 处理秒级时间戳

	// 有时区配置时使用moment处理
	if (timeZoneStore.value) {
		const timeObj = moment(normalizedTime).tz(timeZoneStore.value);
		return timeObj.format(
			options.showSeconds ? "MM-DD HH:mm:ss" : "MM-DD HH:mm"
		);
	}

	// 无时区配置时使用原生Date
	const date = new Date(normalizedTime);
	const parts = [
		addZero(date.getMonth() + 1),
		addZero(date.getDate()),
		addZero(date.getHours()),
		addZero(date.getMinutes()),
	];

	if (options.showSeconds) {
		parts.push(addZero(date.getSeconds()));
	}

	return (
		`${parts[0]}${options.separator}${parts[1]} ${parts[2]}:${parts[3]}` +
		(options.showSeconds ? `:${parts[4]}` : "")
	);
};
const onScroll = (e) => {
	scrollPosition.value = e;
};
const scrolltolower = async () => {
	// 1. 保存当前滚动位置
	await getMsglist();
	console.log(scrollPosition.value);
	nextTick(() => {
		uni.pageScrollTo({
			scrollTop: scrollPosition.value,
			duration: 0,
			selector: ".cell-list",
		});
	});
};
const getNewMsgList = () => {
	let msgLists = msgList.value;
	//一键阅读
	const allReadTime = allReadTimeStore.value;
	const readIds = Array.isArray(readArrStore.value) ? readArrStore.value : [];
	msgLists = msgLists.map((item) => ({
		...item,
		isRead:
			item.create_time < allReadTime || readIds.includes(item.event_id),
	}));
	msgList.value = JSON.parse(JSON.stringify(msgLists));
};
// 获取消息列表
const getMsglist = async () => {
	try {
		const requestParams = { ...query.value };
		if (props.deviceSn) {
			requestParams.device_sn = props.deviceSn;
		}
		const { data } = await getEventApi(requestParams);

		if (data.code === 0) {
			isShowMsg.value = false;
			if (data.data.length > 0) {
				const newData = data.data.map((item) => ({
					...item,
					isRead: false,
				}));

				// 分页逻辑
				query.value.page === 1
					? (msgList.value = newData)
					: (msgList.value = [...msgList.value, ...newData]);

				query.value.page++;
				getNewMsgList();
			} else {
				isEnd.value = true;
			}
		} else {
			console.warn(data.msg);
		}
		isLoading.value = false;
	} catch (error) {
		isLoading.value = false;
		console.error("获取消息失败:", error);
	}
};
const refresh = () => {
	console.log("hh");
	getNewMsgList();
};
// 初始化加载
onShow(() => {
	isLoading.value = true;
	getMsglist();
});
const topHeight = ref("95px");
onMounted(() => {
	// 获取状态栏高度
	// #ifdef APP-PLUS
	const statusBarHeight = ref(0);
	const systemInfo = uni.getSystemInfoSync();
	statusBarHeight.value = systemInfo.statusBarHeight || 0;
	topHeight.value = statusBarHeight.value + 92 + "px";
	// #endif
});
defineExpose({ refresh });
</script>

<style lang="scss" scoped>
.cell-list {
	height: calc(100vh - v-bind(topHeight));
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	top: v-bind(topHeight);
	position: fixed;
	box-sizing: border-box;
	:deep(.u-cell__body) {
		padding: 15px 20px 15px 10px !important;
	}
	.tilte-box {
		display: flex;
		flex-direction: column;
		padding-left: 10px;
		.top-box {
			display: flex;
			justify-content: space-between;
			text {
				margin-bottom: 3px;
				margin-top: 5px;
			}
			.title {
				color: rgba(0, 0, 0, 0.9);
				font-size: 14px;
				font-weight: 600;
				max-width: calc(100% - 100px);
			}
			.time {
				font-size: 12px;
				color: #333333;
			}
		}
		.bottom-text {
			margin-bottom: 7px;
			font-size: 12px;
			color: #bbbbbb;
			margin-right: 10px;
			margin-top: 5px;
		}
	}
	.img-box {
		position: relative;
		.bot {
			position: absolute;
			right: 0;
			width: 10px;
			height: 10px;
			border-radius: 10px;
			background-color: red;
			top: -7px;
			right: 1px;
			z-index: 2;
		}
	}
	:deep(.u-line) {
		width: 85% !important;
		margin-left: 7.5% !important;
	}
}
.loading {
	height: 100vh;
	background-color: #d8d8d8;
}

.pop-content {
	height: calc(70vh - 70px);
	padding: 10px;
	.pop-top {
		display: flex;
		gap: 10px;
		text {
			font-size: 20px;
			font-weight: bold;
			color: #000000;
			line-height: 48px;
			text-align: left;
		}
	}
	:deep(.u-form-item__body__left) {
		width: 210rpx !important;
	}
	:deep(.u-form-item__body__left__content__label) {
		color: #999999;
		font-weight: 400;
		font-size: 32rpx;
	}
	:deep(.u-form-item__body) {
		padding: 0;
		line-height: 60rpx;
		font-size: 32rpx;
		color: #333;
	}
	:deep(.u-form) {
		padding-top: 20rpx;
	}
}
</style>
